﻿using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;
using Mirror;
using UnityEngine.UI;

public class PlayerCTRL : NetworkBehaviour
{

    public float moveSpeed = 4f;
    public float maxFov = 100f;
    public float jumpTime = 2;
    public int maxBullet = 12;
    public int nowBullet;
    public GameObject myEyes;
    public Camera myCam;
    public Vector3 recoilRot = new Vector3(10, 10, 0);

    [Header("鼠标灵敏度")] public float mouseSen = 4f;
    [Header("跳跃力度")] public float jumpForce = 4f;
    [Header("最大生命值")] public float maxHP = 100f;
    [Header("射击距离")] public float shotRang = 500f;
    [Header("子弹预制体")] public GameObject bulletHole;
    [Header("击杀提示")] public RectTransform hitedCurse;

    [SyncVar]
    [Header("目前生命值")] public float nowHP;
    private Rigidbody rb;
    private Animator anim;
    private Material playerMat;
    private WepeanAim aim;
    private RectTransform curse;
    private Vector2 curseTempSize;
    private Vector3 Movement;
    private float xMove;
    private float yMove;
    private float tempY = 0;
    private float tempX = 0;
    private float nowSpeed;
    private float sprintSpeed;
    private float zWiggle;
    private float minFov;
    private Vector3 currentRot;
    private Ray shootRay;
    private bool tempJump;
    private bool temp;
    private GameObject canvas;
    private Image hitedEffect;
    private Text hpText;
    private Transform[] SpownPoses;
    [SyncVar]
    private Color playerColor;


    public AimMode aimMode;
    public enum AimMode
    {
        Sprint,
        Normal,
        Aim,
        Walk,
    }

    public override void OnStartLocalPlayer()
    {
        base.OnStartLocalPlayer();
        CmdSetRandColor();
    }


    void Start()
    {
        nowBullet = maxBullet;
        rb = GetComponent<Rigidbody>();
        myCam = GetComponentInChildren<Camera>();
        myEyes = myCam.gameObject;
        minFov = myCam.fieldOfView;
        anim = GetComponentInChildren<Animator>();
        playerMat = GetComponentInChildren<MeshRenderer>().material;
        aim = GetComponentInChildren<WepeanAim>();

        nowHP = maxHP;
        canvas = GameObject.Find("Canvas");
        hpText = canvas.transform.GetComponentsInChildren<Text>()[0];
        hitedEffect = canvas.transform.GetComponentsInChildren<Image>()[0];
        curse = canvas.transform.Find("curse").GetComponent<RectTransform>();

        SpownPoses = GameObject.FindGameObjectWithTag("SpownPos").GetComponentsInChildren<Transform>();



        if (!isLocalPlayer)
        {
            Destroy(myEyes);
            Destroy(anim.GetComponentInParent<FoloCam>());
            return;
        }
        anim.transform.parent.parent.parent = null;

        //设置冲刺速度为一般速度的两倍
        sprintSpeed = moveSpeed * 2f;
    }

    // Update is called once per frame
    void Update()
    {

        if (playerMat.color != playerColor)
        {
            playerMat.color = playerColor;

        }
        //Debug.LogError(isLocalPlayer);
        if (!isLocalPlayer)
        {
            return;
        }

        Dead(nowHP <= 0);

        hpText.text = "HP: <color=#FFD700>" + nowHP.ToString() + "</color>";
        //Debug.Log(myEyes.transform.localRotation.eulerAngles.x);
        //鼠标控制视角
        #region
        Cursor.lockState = CursorLockMode.Locked;
        tempX = Input.GetAxis("Mouse X") * mouseSen;
        tempY = Input.GetAxis("Mouse Y") * -mouseSen;
        yMove += tempY;
        xMove += tempX;
        this.transform.localRotation = Quaternion.Euler(0, xMove + currentRot.x, 0);
        yMove = Mathf.Clamp(yMove, -90f, 90f);
        myEyes.transform.localRotation = Quaternion.Euler(yMove - currentRot.y, 0, zWiggle);
        #endregion

        //视角左右摇晃
        zWiggle = Input.GetAxis("Horizontal") * 1.5f;

        //跳跃指令输入
        if (Input.GetButtonDown("Jump"))
        {
            tempJump = true;
        }

        Shoot();

        //瞄准
        Aim();

        Reload();

        //瞄准模式准星
        curse.sizeDelta = Vector2.Lerp(curse.sizeDelta, curseTempSize, 0.4f);

        curse.gameObject.SetActive(curse.sizeDelta.x > 21f);

        switch (aimMode)
        {
            case AimMode.Aim:

                curseTempSize = Vector2.one * 20f;
                shootRay = Camera.main.ScreenPointToRay(new Vector2(Screen.width / 2f, Screen.height / 2f));
                break;
            case AimMode.Normal:

                curseTempSize = Vector2.one * 40f;
                shootRay = Camera.main.ScreenPointToRay(new Vector2(Screen.width / 2f, Screen.height / 2f) + Random.insideUnitCircle * 14f);

                break;
            case AimMode.Sprint:

                curseTempSize = Vector2.one * 120f;
                shootRay = Camera.main.ScreenPointToRay(new Vector2(Screen.width / 2f, Screen.height / 2f) + Random.insideUnitCircle * 54f);

                break;
            case AimMode.Walk:
                curseTempSize = Vector2.one * 60f;
                shootRay = Camera.main.ScreenPointToRay(new Vector2(Screen.width / 2f, Screen.height / 2f) + Random.insideUnitCircle * 24f);

                break;
            default:
                curseTempSize = Vector2.one * 40f;
                shootRay = Camera.main.ScreenPointToRay(new Vector2(Screen.width / 2f, Screen.height / 2f) + Random.insideUnitCircle * 14f);

                break;
        }

        //是否移动
        if (Movement == Vector3.zero && jumpTime == 2)
        {
            aimMode = AimMode.Normal;
        }
        else
        {
            aimMode = AimMode.Walk;

        }

        anim.SetInteger("BulletCount", nowBullet);
    }

    private void FixedUpdate()
    {
        if (!isLocalPlayer)
        {
            return;
        }

        //WASD移动
        Movement = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));

        //跳跃
        Jump(ref tempJump);


        this.transform.Translate(Movement * Time.deltaTime * nowSpeed);

    }

    //是否冲刺
    private void Sprint(bool isOn)
    {
        if (isOn)
        {
            aimMode = AimMode.Sprint;

            nowSpeed = sprintSpeed;
            myCam.fieldOfView = Mathf.Lerp(myCam.fieldOfView, maxFov, 0.1f);
        }
        else
        {
            nowSpeed = moveSpeed;
            myCam.fieldOfView = Mathf.Lerp(myCam.fieldOfView, minFov, 0.1f);


        }
    }

    //跳跃
    private void Jump(ref bool isOn)
    {
        Collider[] wallAndFloors = Physics.OverlapSphere(this.transform.position + Vector3.down * 0.62f, 0.4f, LayerMask.GetMask("Floor"));
        if (wallAndFloors.Length != 0)
        {

            //Debug.Log("贴地面");
            jumpTime = 2;
        }

        if (isOn)
        {
            isOn = false;
            Debug.Log("跳起来");

            if (jumpTime > 0)
            {
                rb.isKinematic = true;
                rb.isKinematic = false;
                rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
                jumpTime--;
            }
        }

    }

    public AnimatorStateInfo info;


    private void Shoot()
    {

        info = anim.GetCurrentAnimatorStateInfo(0);
        //Debug.Log(info.IsTag("CanShoot"));

        if (Input.GetButtonDown("Fire1") && nowBullet > 0 && info.IsTag("CanShoot"))
        {
            //击中检测
            RaycastHit hitInfo;

            //射线检测
            //shootRay = Camera.main.ScreenPointToRay(new Vector2(Screen.width / 2f, Screen.height / 2f));

            if (Physics.Raycast(shootRay, out hitInfo, shotRang))
            {
                switch (hitInfo.collider.gameObject.tag)
                {
                    case "Player":

                        //Debug.Log("击中");
                        ShowHitedTip();
                        CmdHitEnemy(20f, hitInfo.collider.gameObject);
                        break;
                    case "Floor":
                        //如果是地板就留下弹孔
                        GameObject bH = Instantiate(bulletHole, hitInfo.point, Quaternion.LookRotation(hitInfo.normal));
                        bH.transform.parent = hitInfo.collider.transform;
                        Destroy(bH, 4f);
                        break;
                    default:

                        break;
                }

                //Debug.Log("Hit!!");
                // .SetActive(false);
            }

            //Calls animation on the gun that has the relevant animation events that will fire
            anim.SetTrigger("Fire");
            //子弹数减一；
            nowBullet--;

            //后坐力计算
            recoilRot.x = Random.Range(-3f, 3f);
            recoilRot.y = Random.Range(6f, 10f);
            //currentRot = Vector3.zero;
            xMove += currentRot.x;
            yMove -= currentRot.y;
            temp = true;
        }

        //后坐力叠加实现
        #region
        if (temp)
        {
            currentRot = Vector3.Lerp(currentRot, recoilRot, Time.deltaTime * 40f);
            if ((currentRot - recoilRot).magnitude < 0.1f)
            {
                temp = false;
            }

        }
        else
        {
            currentRot = Vector3.Lerp(currentRot, Vector3.zero, Time.deltaTime * 10f);
        }
        #endregion


    }



    private void Reload()
    {

        if (nowBullet < maxBullet)
        {
            anim.SetBool("Reload", Input.GetButtonDown("Reload"));
            if (Input.GetButtonDown("Reload"))
            {
                nowBullet = 0;
            }
        }
    }

    //瞄准
    private void Aim()
    {
        if (Input.GetMouseButton(1))
        {
            aim.transform.position = Vector3.Lerp(aim.transform.position, aim.aimPos.position, 0.24f);
            myCam.fieldOfView = Mathf.Lerp(myCam.fieldOfView, 60f, 0.1f);

            aimMode = AimMode.Aim;
            nowSpeed = moveSpeed;
        }
        else
        {
            aim.transform.position = Vector3.Lerp(aim.transform.position, aim.nomalPos.position, 0.12f);

            Sprint(Input.GetButton("Sprint"));


        }

    }

    //被击中处理
    [Command]
    public void CmdHitEnemy(float dmg, GameObject go)
    {
        Debug.Log("hited");
        go.GetComponent<PlayerCTRL>().nowHP -= dmg;
        TargetHitEnemy(go.GetComponent<NetworkIdentity>().connectionToClient);
    }

    [TargetRpc]
    private void TargetHitEnemy(NetworkConnection conect)
    {
        //go.GetComponent<PlayerCTRL>().hited = true;
        conect.identity.GetComponent<PlayerCTRL>().StartCoroutine(BeHited());
    }

    //被击中提示
    private IEnumerator BeHited()
    {

        hitedEffect.enabled = true;
        yield return new WaitForSeconds(0.08f);
        hitedEffect.enabled = false;

    }
    //击杀提示
    private void ShowHitedTip()
    {
        RectTransform temphitedCurse = Instantiate(hitedCurse.gameObject, curse.parent).GetComponent<RectTransform>();

        float tweenTime = 0.2f;
        DOTween.To(() => temphitedCurse.sizeDelta, x => temphitedCurse.sizeDelta = x, Vector2.one * 100f, tweenTime).OnComplete(delegate () { Destroy(temphitedCurse.gameObject); });


        foreach (var Image in temphitedCurse.GetComponentsInChildren<Image>())
        {
            Image.DOFade(0, tweenTime);
        }

    }

    //死亡
    private void Dead(bool isOn)
    {
        if (isOn)
        {
            this.transform.position = SpownPoses[Random.Range(0, SpownPoses.Length)].position;
            CmdHeal(maxHP);
        }
    }

    //生命值恢复
    [Command]
    public void CmdHeal(float HP)
    {

        nowHP = HP;
    }

    //连接时设置颜色
    [Command]
    public void CmdSetRandColor()
    {
        playerColor = Random.ColorHSV();
    }

}
